package com.camerareader.upload_list;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.PowerManager;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;

import com.alibaba.sdk.android.oss.ClientConfiguration;
import com.alibaba.sdk.android.oss.ClientException;
import com.alibaba.sdk.android.oss.OSS;
import com.alibaba.sdk.android.oss.OSSClient;
import com.alibaba.sdk.android.oss.ServiceException;
import com.alibaba.sdk.android.oss.common.auth.OSSCredentialProvider;
import com.alibaba.sdk.android.oss.common.auth.OSSCustomSignerCredentialProvider;
import com.alibaba.sdk.android.oss.common.auth.OSSFederationCredentialProvider;
import com.alibaba.sdk.android.oss.common.auth.OSSFederationToken;
import com.alibaba.sdk.android.oss.common.auth.OSSPlainTextAKSKCredentialProvider;
import com.alibaba.sdk.android.oss.common.auth.OSSStsTokenCredentialProvider;
import com.alibaba.sdk.android.oss.model.PutObjectRequest;
import com.alibaba.sdk.android.oss.model.PutObjectResult;
import com.fileoperation.model.MessageEvent;
import com.fileoperation.model.Photo;
import com.fileoperation.model.SaveUserInfoEvent;
import com.fileoperation.model.StateChangedEvent;
import com.fileoperation.user.UserInfo;
import com.nettools.Constants;
import com.nettools.NetTools;
import com.nettools.NetUtils;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import okhttp3.Response;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/**
 * Created by Administrator on 2016-12-22.
 */

public class UploadService extends Service {

    private final String TAG = "UploadService";
    private QueueLinked queueLinked = new QueueLinked();
    private boolean onGo = true;
    private OSS oss;
    private Photo current;

    // 申请设备电源锁
    private PowerManager.WakeLock mWakeLock;


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.w(TAG, "service onBind");
        return new MyBinder();
    }


    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(Photo photo){
        Log.w(TAG, "收到图片，加入上传队列：" + photo.toString());
        addTask(photo);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onToastMessage(MessageEvent e){
        Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
    }




    @Override
    public void onCreate() {
        super.onCreate();
        Log.w(TAG, "service created");
        EventBus.getDefault().register(this);

//        acquireWakeLock();



//        OSSCredentialProvider credentialProvider = new OSSFederationCredentialProvider() {
//            @Override
//            public OSSFederationToken getFederationToken() {
//                OSSFederationToken token = new OSSFederationToken();
//                token.setExpiration(System.currentTimeMillis()+1000*60*60*24);
//                token.setSecurityToken(UserInfo.getInstance().getAccessToken());
//                token.setTempAk(Constants.AccessKeyId);
//                token.setTempSk(Constants.AccessKeySecret);
//                return token;
//            }
//        };

        OSSCredentialProvider credentialProvider = new OSSPlainTextAKSKCredentialProvider(Constants.AccessKeyId,Constants.AccessKeySecret);
//        OSSCredentialProvider credentialProvider = new OSSCustomSignerCredentialProvider() {
//            @Override
//            public String signContent(String content) {
//                // 您需要在这里依照OSS规定的签名算法，实现加签一串字符内容，并把得到的签名传拼接上AccessKeyId后返回
//                // 一般实现是，将字符内容post到您的业务服务器，然后返回签名
//                // 如果因为某种原因加签失败，描述error信息后，返回nil
//                // 以下是用本地算法进行的演示
//                //requet server
//
//                try {
//                    Response signData = NetUtils.getInstance().getSignData(content);
//                    JSONObject jsonResponse = new JSONObject(signData.body().string());
//                    if (jsonResponse.optBoolean(Constants.STATUS)){
//                        String signContent = jsonResponse.optString(Constants.DATA);
//                        Log.w(TAG, "获取signData = " + signData);
//                        return signContent;
//                    }else {
//                        throw new Exception("获取signData失败");
//                    }
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//                return null;
//            }
//        };
        oss = new OSSClient(getApplicationContext(), Constants.OSS_ENDPOINT, credentialProvider);

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.w(TAG, "service started");
        onGo = true;
        Observable.create(new Observable.OnSubscribe<Photo>() {
            @Override
            public void call(Subscriber<? super Photo> subscriber) {
                try {
                    while (onGo) {
                        current = queueLinked.dequeue();
                        if (current != null) {
                            Log.w(TAG, "开始上传任务。。。 " + current.toString());
                            EventBus.getDefault().post(new StateChangedEvent());
                            uploadFile(current, subscriber);
                            current = null;
                        } else {
                            Log.w(TAG, "没有上传任务。。。");
                            Thread.sleep(1000);
                        }
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        })
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<Photo>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(Photo photo) {
                        Toast.makeText(UploadService.this, "上传照片成功： " + photo.getPath() + photo.getFileName(), Toast.LENGTH_SHORT).show();
                    }
                });


        return super.onStartCommand(intent, flags, startId);

    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.w(TAG, "service onUnBind");
        return super.onUnbind(intent);
    }

    public int getQueueNum(){
        return queueLinked.getCount() + (current == null ? 0 : 1);
    }

    public ArrayList<Photo> getQueueList(){
        ArrayList<Photo> list = queueLinked.getQueueList();
        if (list == null) {
            if (current == null) return null;
            ArrayList<Photo> temp = new ArrayList<>(1);
            temp.add(current);
            return temp;
        }
        if (current != null) list.add(current);
        return list;
    }

    public void clearUploadList(){
        ArrayList<Photo> list = getQueueList();
        if(list != null && list.size() > 0){
            list.clear();
        }
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        onGo = false;
//        releaseWakeLock();
        EventBus.getDefault().unregister(this);
        Log.w(TAG, "service onDestroy");
    }


    public class MyBinder extends Binder {
        /**
         * 获取Service的方法
         *
         * @return 返回PlayerService
         */
        public UploadService getService() {
            return UploadService.this;
        }
    }

    public void addTask(Photo photo) {
        if(!queueLinked.hasPhoto(photo)) {
            queueLinked.enqueue(photo);
            EventBus.getDefault().post(new StateChangedEvent());
        }
    }
    public void addTask(ArrayList<Photo> list){
        if (list == null) return;
        for (int i = 0; i < list.size(); i++){
            queueLinked.enqueue(list.get(i));
        }
        EventBus.getDefault().post(new StateChangedEvent());
    }

    private void uploadFile(Photo photo, Subscriber subscriber) {
        // 构造上传请求
        String objectKey = NetTools.generateObjectKey(photo.getFileName());
        String objectPath = photo.getPath() + photo.getFileName();
        Log.w(TAG, "objectKey = " + objectKey);
        Log.w(TAG, "objectPath = " + objectPath);
        PutObjectRequest put = new PutObjectRequest(Constants.OSS_BUCKET, objectKey, objectPath);
// 文件元信息的设置是可选的
// ObjectMetadata metadata = new ObjectMetadata();
// metadata.setContentType("application/octet-stream"); // 设置content-type
// metadata.setContentMD5(BinaryUtil.calculateBase64Md5(uploadFilePath)); // 校验MD5
// put.setMetadata(metadata);
        try {
            PutObjectResult putResult = oss.putObject(put);
            photo.setCloudPath(objectKey);
            Log.d("PutObject", "UploadSuccess");
            Log.d("ETag", putResult.getETag());
            Log.d("RequestId", putResult.getRequestId());
//            Response syncServerResponse = NetUtils.getInstance().sendUploadConsequence(photo.getSize(), photo.getCloudPath());
//            String json = syncServerResponse.body().string();
//            JSONObject jsonResponse = new JSONObject(json);
//            if (jsonResponse.optBoolean(Constants.STATUS)){
                File uploadPhoto = new File(photo.getPath() + photo.getFileName());
                if (uploadPhoto.exists()) uploadPhoto.delete();
                subscriber.onNext(photo);
                EventBus.getDefault().post(new StateChangedEvent());
//            }else {
//                throw new Exception("同步服务器出错!");
//            }
//            Log.d(TAG, "同步服务器结果=" + syncServerResponse);
        } catch (ClientException e) {
            // 本地异常如网络异常等
            e.printStackTrace();
        } catch (ServiceException e) {
            // 服务异常
            Log.e("RequestId", e.getRequestId());
            Log.e("ErrorCode", e.getErrorCode());
            Log.e("HostId", e.getHostId());
            Log.e("RawMessage", e.getRawMessage());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private void acquireWakeLock()
    {
        if (null == mWakeLock)
        {
            PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
            mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "服务名");
            if (null != mWakeLock) {
                mWakeLock.acquire();
            }
        }
    }

    // 释放设备电源锁
    private void releaseWakeLock()
    {
        if (null != mWakeLock)
        {
            mWakeLock.release();
            mWakeLock = null;
        }
    }
}
